<template>
  <NpDialog :visible.sync="dialogPvVisible" width="640px">
    <div class="title">导入设备</div>
    <el-form :model="ruleForm" :rules="rules" ref="ruleFormRef" label-width="82px" class="from_warp">
      <el-form-item label="上传文档" prop="">
        <div class="con">
          <div class="top">
            <el-upload class="upload_warp" ref="upload_ref" drag action="#" multiple :limit="1" :file-list="fileList"
              v-show="!handleFileObjLength" :auto-upload="false" :on-change="handleChange">
              <np-svg-icon icon-class="equipment-list-file-excel-2-fill" :w-h="['80px']" />
              <div class="el-upload__text">将文件拖拽到这里</div>
              <el-button>选择文件</el-button>
            </el-upload>
            <div class="have_file_warp" v-show="handleFileObjLength">
              <np-svg-icon icon-class="equipment-list-ic_success" :w-h="['48px']" />
              <div>已识别有效数据<span>{{ handleFileObjLength }}</span>条</div>
            </div>
          </div>
          <div class="tisp_watp">
            <div class="row1" @click="downloadTemplateClick">
              <i class="el-icon-download" />
              下载模板
            </div>
            <div class="row2">
              <i class="el-icon-info" />
              每次最多可导入1,000台设备
            </div>
          </div>
        </div>
      </el-form-item>
      <el-form-item label="品牌" prop="menufacturerId">
        <el-select v-model="ruleForm.menufacturerId" placeholder="请选择品牌">
          <el-option v-for="(item, index) in brandOptions" :key="'br' + index" :label="item.menufacturer"
            :value="item.id" />
        </el-select>
      </el-form-item>
    </el-form>
    <div class="fotter">
      <el-button type="info" plain class="btn1" @click="uploadCancelClick" :disabled="submitLoading">取消</el-button>
      <el-button type="warning" @click="uploadImportClick('ruleFormRef')" :disabled="submitDisabled"
        :loading="submitLoading">导入</el-button>
    </div>
  </NpDialog>
</template>
<script>
import NpDialog from "@/components/np/Dialog/index.vue"
import axios from 'axios'
import { downloadFile } from '@/api/public'
import XLSX from 'xlsx'
import { exportFile, parseTime } from "@/utils"
import devicesTemplateXlsxList from "@/views/equipment-management/list/components/devicesTemplateXlsxList"
import { batchImportDevices } from '@/api/equipment-management/list'

export default {
  components: {
    NpDialog
  },
  props: {
    visible: {
      type: Boolean,
      default: false
    },
    brandOptions: {
      type: Array,
      default: () => {
        return []
      }
    },
  },
  data() {
    let com_blur__rule = [{ required: true, message: '此字段为必填。', trigger: 'blur' }],
      com_change__rule = [{ required: true, message: '此字段为必填。', trigger: 'change' }];
    return {
      dialogPvVisible: false,

      ruleForm: {
        menufacturerId: '',
      },
      rules: {
        menufacturerId: com_change__rule,
      },

      fileList: [],
      handleFileObj: [],

      upload_file_loading: false,
      upload_submit_loading: false,
    }
  },
  watch: {
    visible: {
      handler(newVal) {
        this.dialogPvVisible = newVal;
        if (!newVal) {
          this.resetFieldsFrom()
        }
      }
    }
  },
  computed: {
    handleFileObjLength() {
      return this.handleFileObj.length
    },
    submitDisabled() {
      return this.upload_submit_loading || !this.handleFileObjLength
    },
    submitLoading() {
      return this.upload_submit_loading
    },
  },
  methods: {
    resetFieldsFrom() {
      Object.keys(this.ruleForm).forEach(el => {
        this.ruleForm[el] = ''
      })
    },
    downloadTemplateClick() {
      // ${process.env.VUE_APP_BASE_API}
      let url = `/the-project-itself/亲选相册设备导入表.xlsx`
      axios.get(url, { responseType: 'blob' })
        .then(res => {
          let fileName = "亲选相册设备导入表.xlsx";
          exportFile(res.data, fileName);
        })
        .catch(error => {
          console.error('Error fetching the file:', error);
        });
    },
    uploadCancelClick() {
      this.dialogPvVisible = false
      this.fileList = []
      this.handleFileObj = []
      this.$refs['ruleFormRef'].resetFields()
      this.$emit("update:visible", this.dialogPvVisible)
    },
    uploadImportClick(formName) {
      if (this.upload_submit_loading) {
        return
      }
      this.$refs[formName].validate((valid) => {
        if (valid) {
          let pans = this.handleFileObj.map(el => {
            el.menufacturerId = this.ruleForm.menufacturerId || ''
            return el
          })
          this.upload_submit_loading = true;
          batchImportDevices(pans).then(res => {
            if (res.code === 200) {
              this.$message.success('上传成功!')
              setTimeout(() => {
                this.uploadCancelClick()
                this.$emit('importSuccess', true)
              }, 400)
              return
            } else {
              this.$message.error(res.message || '上传失败。')
            }
            this.upload_submit_loading = false;
          }).catch(err => {
            this.$message.error('网络或者连接问题。')
            this.upload_submit_loading = false;
          })
        } else {
          console.log('error submit!!');
          return false;
        }
      });
    },
    handleChange(file, fileList) {
      this.fileList = [file];
      this.handleFileObj = [];

      if (!this.isExcel(file)) {
        this.$message.error('仅支持上传.xlsx、.xls、.csv后缀文件')
        this.fileList = [];
        this.$refs.upload_ref.clearFiles();
        return
      }

      this.upload_file_loading = true;
      this.readerData(file.raw).then(res => {
        this.handleFileObj = res
      }).catch(err => {
        // console.log(err);
        let { message } = err
        this.$message.error(message || '导入的数据有问题')
        this.fileList = [];
      }).finally(() => {
        this.upload_file_loading = false;
      })
    },
    readerData(rawFile) {
      return new Promise((resolve, reject) => {
        const reader = new FileReader()
        // reader.readAsBinaryString(rawFile);
        reader.onload = e => {
          const data = e.target.result
          const workbook = XLSX.read(data, {
            type: 'array',
            cellDates: true,// 将日期单元格直接解析为 Date 对象
          })
          const firstSheetName = workbook.SheetNames[0]
          const worksheet = workbook.Sheets[firstSheetName]
          // console.log("打印1---->>>", worksheet);

          const header = this.getHeaderRow(worksheet)
          const results = XLSX.utils.sheet_to_json(worksheet)

          // console.log("打印2---->>>", { header, results });

          let maxNum = 1000, everyNum = 1000, finalArr = [], orgArrLen = results.length;
          if (orgArrLen === 0) {
            this.$message.error(`检测到导入表数据为空，请重新上传！`)
            this.$refs.upload_ref.clearFiles();
            return
          }
          if (orgArrLen > maxNum) {
            this.$message.error(`一次只能上传${maxNum}条数据`)
            this.$refs.upload_ref.clearFiles();
            return
          }

          try {
            let re_obj = {
              'deviceCode': '序列号',
            },
              need_int = ['storage'],
              need_date = ['dateProduction'];
            let date_cur = new Date(),
              storage_key = '设备容量',
              storage_unit = ['TB', 'GB', 'T', 'G', 'tb', 'gb', 't', 'g'],
              isNumLetter = (str) => /^[A-Za-z0-9]+$/.test(str),
              splitStrLettersNum = (str) => {
                const letters = str.match(/[a-zA-Z]+/g) || []; // 匹配所有字母
                const numbers = str.match(/\d+/g) || []; // 匹配所有数字
                return { letters, numbers };
              },
              countSubstring = (str, sub) => {
                /**
                 * 判断一个字符串中子串出现的次数
                 * @str 母字符串
                 * @sub 子字符串
                 */
                return (str.split(sub).length - 1);
              },
              orgsList = devicesTemplateXlsxList;
            let pans = results.map((el, index, orgArr) => {
              // 判断哪一行必填数据有为空的
              if (!el[re_obj.deviceCode]) {
                throw new Error(`检测到第（${index + 1}）条数据序列号不存在，重新上传`);
              }
              // 判断出有重复的数据，终止循环
              if (index >= 1) {
                if (el[re_obj.deviceCode] === orgArr[index - 1].deviceCode) {
                  throw new Error(`检测到第（${index + 1}）条数据附件存在重复的数据，请您仔细查看序列号是否有重复，重新上传`);
                }
              }
              for (let key in el) {
                let need_v,
                  need_k = orgsList[key];
                if (key === '出厂日期') {
                  need_v = el[key];
                  need_v = need_v ? need_v : date_cur;
                  need_v = parseTime(need_v, '{y}-{m}-{d} {h}:{i}:{s}')
                } else if (key === storage_key && el[key]) {
                  need_v = el[key];
                  need_v = String(need_v) || ''
                  // console.log(11111111, index, need_v, need_v[1] === '.', countSubstring(need_v, '.'));

                  if (!Number(need_v[0]) && !(Number(need_v[0]) === 0)) {
                    console.log('00000000000');

                    // 判断一个字符串是否以数字开头，不是就报错
                    throw new Error(`检测到第（${index + 1}）条数据${storage_key}单位或者容量填写错误，重新上传`);
                  }
                  let isDecimal = countSubstring(need_v, '.') === 1, decimal_v = need_v, pass_0_v = '', less_0_v = '';
                  console.log(countSubstring(need_v, '.'));

                  if (isDecimal) {
                    let arr = decimal_v.split('.');
                    pass_0_v = arr[0]
                    if (!Number(pass_0_v) && !(Number(pass_0_v) === 0)) {
                      console.log('ppppppp');
                      throw new Error(`检测到第（${index + 1}）条数据${storage_key}单位或者容量填写错误，重新上传`);
                    }
                    less_0_v = arr[1]
                    need_v = less_0_v
                  } else {
                    console.log('uuuuuuuuu');

                    if (!isNumLetter(need_v)) {
                      console.log('rrrrrrr');
                      throw new Error(`检测到第（${index + 1}）条数据${storage_key}单位或者容量填写错误，重新上传`);
                    }
                  }

                  let LN = splitStrLettersNum(need_v),
                    l = LN.letters.join(''),
                    n = LN.numbers.join('');
                  // console.log(index, n, l);
                  // console.log(index, LN);
                  if (!n || n === 0) {
                    throw new Error(`检测到第（${index + 1}）条数据${storage_key}单位或者容量填写错误,单位只能为:${storage_unit.join(',')}，重新上传`);
                  }
                  if (!(countSubstring(need_v, n) === 1 && (!l || (countSubstring(need_v, l) === 1 && storage_unit.includes(l))))) {
                    throw new Error(`检测到第（${index + 1}）条数据${storage_key}单位或者容量填写错误,单位只能为:${storage_unit.join(',')}，重新上传`);
                  }
                  /**
                   * 导入xls表等，没有单位默认就是 TB
                   * 默认存储 GB 列表默认显示GB，如果大于 1Tb 单位就是 TB
                   */
                  let t = 't', g = 'g';
                  if (isDecimal) {
                    n = '' + pass_0_v + '.' + need_v.replace(/[a-zA-Z]/g, "");
                  }
                  console.log(n);

                  if (!l || less_0_v.toLowerCase().includes(t)) {
                    // TB
                    need_v = Number(n) * 1024;
                  } else {
                    // GB
                    need_v = Number(n);
                  }
                } else {
                  need_v = el[key].trim();
                }
                if (need_int.includes(need_k)) {
                  el[need_k] = Number(need_v)
                } else if (need_date.includes(need_k)) {
                  el[need_k] = parseTime(need_v, '{y}-{m}-{d} {h}:{i}:{s}')
                } else {
                  el[need_k] = String(need_v)
                }
                delete el[key]
              }
              // activedState 激活状态,U:未激活,A:已激活
              el.activedState = 'A'
              return el
            })
            // console.log("pans---->", pans, results);
            resolve(pans)
          } catch (error) {
            reject(error)
          }
        }
        reader.readAsArrayBuffer(rawFile)
      })
    },
    getHeaderRow(sheet) {
      const headers = []
      const range = XLSX.utils.decode_range(sheet['!ref'])
      let C
      const R = range.s.r
      /* start in the first row */
      for (C = range.s.c; C <= range.e.c; ++C) { /* walk every column in the range */
        const cell = sheet[XLSX.utils.encode_cell({ c: C, r: R })]
        /* find the cell in the first row */
        let hdr = 'UNKNOWN ' + C // <-- replace with your desired default
        if (cell && cell.t) hdr = XLSX.utils.format_cell(cell)
        headers.push(hdr)
      }
      return headers
    },
    isExcel(file) {
      return /\.(xlsx|xls|csv)$/.test(file.name)
    },
  }
}
</script>
<style lang="scss" scoped>
.title {
  padding-bottom: 32px;
  font-size: 18px;
  font-weight: 500;
  line-height: 24px;
  color: #15181D;
}

.con {
  display: flex;
  flex-direction: column;

  .top {}

  .tisp_watp {
    padding: 16px 0 18px;
    display: flex;
    justify-content: space-between;
    align-items: center;
    font-size: 14px;
    line-height: 18px;

    .row1 {
      cursor: pointer;
      color: #C27B55;
      cursor: pointer;
    }

    .row2 {
      cursor: pointer;
      text-align: right;
      color: #8B8B8B;
    }
  }
}

.from_warp {
  .el-select {
    width: 100%;
    padding-bottom: 18px;
  }
}

.fotter {
  display: flex;
  justify-content: right;
  align-items: center;

  .btn1 {
    margin-right: 12px;
  }
}

@mixin com_upload_warp {
  width: 100%;
  min-height: 240px;
  border-radius: 12px;
  background-color: #F5F5F5;
  display: flex;
  justify-content: center;
  align-items: center;
  flex-direction: column;
}

.have_file_warp {
  @include com_upload_warp;
  border: 1px dashed #EAEAEA;

  &>div {
    padding-top: 20px;
    font-size: 14px;
    line-height: 18px;
    text-align: center;
    color: #8B8B8B;

    &>sapn {
      color: #2BA471;
    }
  }
}

::v-deep {
  .upload_warp {
    .el-upload-list {
      display: none;
    }

    .el-upload,
    .el-upload-dragger {
      @include com_upload_warp;
    }

    .el-icon-upload {
      margin: 0;
    }

    .el-upload__text {
      padding: 20px 0;
      font-size: 14px;
      line-height: 18px;
      color: #CCCCCC;
    }
  }
}
</style>